﻿using System;
using System.Collections.Generic;
using NakedObjects;
using System.Linq;

namespace HRMDomain
{
    public class Employee:Base
    {

        public virtual string LastName { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string EmployeeId { get; set; }
        public virtual EmployeeClass EmployeeClass
        {
            get { return EmployeeClasses.Where(w => w.EndDate == null).FirstOrDefault(); }
        }
        public virtual Location CurrentLocation
        {
            get
            {
                return LocationHistory.Where(w => w.EndDate == null).Select(s => s.Location).FirstOrDefault();
            }
        }
        public virtual AbsenceStage AbsenceMgtStage
        {
            get { return AbsenceStages.Where(w => w.EndDate == null).FirstOrDefault(); }
        }
        #region LocationHistory (collection)
        private ICollection<EmployeeLocation> _LocationHistory = new List<EmployeeLocation>();
        [Hidden]
        public virtual ICollection<EmployeeLocation> LocationHistory
        {
            get
            {
                return _LocationHistory;
            }
            set
            {
                _LocationHistory = value;
            }
        }
        #endregion
        #region EmployeeClasses (collection)
        private ICollection<EmployeeClass> _EmployeeClasses = new List<EmployeeClass>();

        public virtual ICollection<EmployeeClass> EmployeeClasses
        {
            get
            {
                return _EmployeeClasses;
            }
            set
            {
                _EmployeeClasses = value;
            }
        }

        #endregion

        #region AbsenceStages (collection)
        private ICollection<AbsenceStage> _AbsenceStages = new List<AbsenceStage>();
        [Hidden]
        public virtual ICollection<AbsenceStage> AbsenceStages
        {
            get
            {
                return _AbsenceStages;
            }
            set
            {
                _AbsenceStages = value;
            }
        }
        #endregion
        #region Performance (collection)
        private ICollection<Performance> _Performance = new List<Performance>();

        public virtual ICollection<Performance> Performance
        {
            get
            {
                return _Performance;
            }
            set
            {
                _Performance = value;
            }
        }
        #endregion
        #region Injuries (collection)
        private ICollection<Injury> _Injuries = new List<Injury>();

        public virtual ICollection<Injury> Injuries
        {
            get
            {
                return _Injuries;
            }
            set
            {
                _Injuries = value;
            }
        }
        #endregion
        #region FeedbackList (collection)
        private ICollection<Feedback> _FeedbackList = new List<Feedback>();

        public virtual ICollection<Feedback> FeedbackList
        {
            get
            {
                return _FeedbackList;
            }
            set
            {
                _FeedbackList = value;
            }
        }
        #endregion
        public string Title()
        {
            TitleBuilder t = new TitleBuilder();
            if (Container.IsPersistent(this))
            {
                t.Append(LastName.ToUpper()).Append(",", FirstName);
            }
            else
            {
                t.Append("NEW EMPLOYEE RECORD");
            }

            return t.ToString();
        }


        #region LocationTransfer (Action)

        [MemberOrder(Sequence = "2")]
        public void LocationTransfer(Location Location, DateTime StartDate)
        {
            EmployeeLocation currentLocation = LocationHistory.Where(w => w.EndDate == null).FirstOrDefault();
            EmployeeLocation newLocation = Container.NewTransientInstance<EmployeeLocation>();

            if (currentLocation != null)
            {
                currentLocation.EndDate = StartDate;
            }


            newLocation.Employee = this;
            newLocation.StartDate = StartDate;
            newLocation.Location = Location;
            newLocation.EndDate = null;

            Container.Persist<EmployeeLocation>(ref newLocation);
            Container.InformUser("Home Location Updated.");

        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion

        #region ListLocationHistory (Action)

        [MemberOrder(Sequence = "1")]
        public IQueryable<EmployeeLocation> ListLocationHistory()
        {
            return LocationHistory.AsQueryable();
        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion

        #region ChangeEmployeeClass (Action)

        [MemberOrder(Sequence = "1")]
        public void ChangeEmployeeClass(EmployeeClassType type, DateTime StartDate)
        {
            EmployeeClass currenttype = EmployeeClasses.Where(w => w.EndDate == null).FirstOrDefault();
            EmployeeClass newtype = Container.NewTransientInstance<EmployeeClass>();

            if (currenttype != null)
            {
                currenttype.EndDate = StartDate;
            }

            newtype.StartDate = StartDate;
            newtype.Class = type;
            newtype.Employee = this;
            newtype.EndDate = null;

            Container.Persist<EmployeeClass>(ref newtype);
            Container.InformUser("Employee Class updated.");


        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion


        #region AddAbsenceStage (Action)

        [MemberOrder(Sequence = "1")]
        public void AddAbsenceStage(AbsenceStageType stage, DateTime StartDate)
        {
            AbsenceStage currentstage = AbsenceStages.Where(w => w.EndDate == null).FirstOrDefault();
            AbsenceStage newstage = Container.NewTransientInstance<AbsenceStage>();

            if (currentstage != null)
            {
                currentstage.EndDate = StartDate;
            }

            newstage.StartDate = StartDate;
            newstage.Stage = stage;
            newstage.Employee = this;
            newstage.EndDate = null;

            Container.Persist<AbsenceStage>(ref newstage);
            Container.InformUser("Absence Management Stage Updated.");


        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion

        #region AddPerformanceEvent (Action)

        [MemberOrder(Sequence = "1")]
        public Performance AddPerformanceEvent(DateTime Date, PerformanceCategory Category)
        {
            Performance newPerformance = Container.NewTransientInstance<Performance>();
            newPerformance.Date = Date;
            newPerformance.Category = Category;

            Container.Persist<Performance>(ref newPerformance);
            _Performance.Add(newPerformance);
            Container.InformUser("Performance Event Added.");
            return newPerformance;
        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion

        #region AddInjury (Action)

        [MemberOrder(Sequence = "1")]
        public Injury AddInjury(DateTime Date, InjuryType InjuryType)
        {
            Injury newInjury = Container.NewTransientInstance<Injury>();
            newInjury.OccurenceDate = Date;
            newInjury.Type = InjuryType;
            newInjury.Employee = this;

            Container.Persist<Injury>(ref newInjury);
            _Injuries.Add(newInjury);
            Container.InformUser("Injury added.");
            return newInjury;

        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion

        #region AddFeedback (Action)

        [MemberOrder(Sequence = "1")]
        public void AddFeedback(FeedbackCategory Category, DateTime Date, [MultiLine]string Details)
        {
            Feedback newFeedback = Container.NewTransientInstance<Feedback>();

            newFeedback.Type = Category;
            newFeedback.Date = Date;
            newFeedback.Details = Details;

            Container.Persist<Feedback>(ref newFeedback);

            this._FeedbackList.Add(newFeedback);
            Container.InformUser("Feedback Added.");
        }

        // Use 'hide', 'dis', 'val', 'actdef', 'actcho' shortcuts to add supporting methods here.
        #endregion

    }
}
